Skip to content

hardening(proxy): bound the remaining unbounded worker collections - #414

Merged
debugmcpdev merged 1 commit into
mainfrom
hardening/405-bounded-collections
Aug 22, 2026
Merged

hardening(proxy): bound the remaining unbounded worker collections#414
debugmcpdev merged 1 commit into
mainfrom
hardening/405-bounded-collections

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Fixes #405

Closes the umbrella from the post-#395 retention audit: the remaining unbounded in-memory collections where a misbehaving adapter or debuggee turns into unbounded worker memory. Each is bounded per its semantic, with an overflow test per site (precedent: OUTPUT_BUFFER_CAP's cap + accounting).

Bounds

Site Bound Overflow behavior
DapProxyWorker.preConnectQueue MAX_QUEUED_COMMANDS (256) Error response on the live requestId ("pre-connect queue overflow … adapter never became ready")
DapProxyWorker.commandQueue MAX_QUEUED_COMMANDS (256) Error response on the live requestId ("command queue overflow … adapter is not draining"); the queue is neither grown nor drained
ChildSessionManager.storedBreakpoints lifecycle Cleared in shutdown() (was the one map that outlived it); a file clearing to zero breakpoints deletes its key instead of storing an empty array — a fresh child never saw them, so replaying [] was a no-op
CdpFunctionBreakpointBridge.scriptUrls MAX_SCRIPT_URLS (10,000), FIFO Oldest scriptParsed entry evicted; a stale entry only costs a fallback url lookup. Growth vector: long-lived JS debuggees with module churn (dev servers, jest watch). detach() already reaches the existing clear

Silent eviction was ruled out for the queues deliberately: every queued command holds a live requestId, so dropping one would hang the client forever — overflow must answer.

Tests (TDD, watched fail first)

  • Worker: pre-connect and policy-queue overflow each get an error response and leave the queue untouched.
  • ChildSessionManager: shutdown() clears stored breakpoints; empty-set store deletes the key.
  • Bridge: 10,010 scriptParsed events → map holds exactly the cap, oldest evicted, newest intact.
  • Full npm test green, npm run lint clean.

This closes out the memory-footprint audit follow-ups (#399#405).

🤖 Generated with Claude Code

Closes the post-#395 retention audit umbrella (issue #405):

- DapProxyWorker.preConnectQueue and commandQueue capped at
  MAX_QUEUED_COMMANDS (256); overflow answers the live requestId with an
  error response instead of queueing forever (silent eviction would hang
  the client)
- ChildSessionManager.storedBreakpoints cleared in shutdown() and a file
  clearing to zero breakpoints deletes its key (replaying [] to a fresh
  child was a no-op)
- CdpFunctionBreakpointBridge.scriptUrls FIFO-capped at MAX_SCRIPT_URLS
  (10k) for long-lived JS debuggees with module churn

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@debugmcpdev
debugmcpdev merged commit f037e99 into main Aug 22, 2026
8 checks passed
@debugmcpdev
debugmcpdev deleted the hardening/405-bounded-collections branch August 22, 2026 04:27
@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hardening(proxy): bound the remaining unbounded worker collections (queues, storedBreakpoints, scriptUrls)

2 participants